//#define CQ_FRK_FM3
//#define CQFM3DUINO
//#define CQ_FRK_RX62N
//#define CQ_FRK_NXP_ARM
//#define KS_MB9BF506
//#define KS_MB9BF568
#define GR_SAKURA

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using MicroLiquidCrystal;

namespace NetworkClock
{
    public class DfRobotLcdShield : MicroLiquidCrystal.Lcd
    {
        readonly OutputPort backlight;
        readonly AnalogInput analog;

        const int a_KEY_UP = 225;
        const int a_KEY_DOWN = 500;
        const int a_KEY_LEFT = 800;
        const int a_KEY_SELECT = 900;
        const int a_KEY_RIGHT = 50;
        const int a_KEY_NONE = 1000;

#if CQFM3DUINO
        const Cpu.Pin d8 = (Cpu.Pin)0x3e;     // Pins.GPIO_PIN_D8
        const Cpu.Pin d9 = (Cpu.Pin)0x3b;     // Pins.GPIO_PIN_D9
        const Cpu.Pin d4 = (Cpu.Pin)0x39;     // Pins.GPIO_PIN_D4
        const Cpu.Pin d5 = (Cpu.Pin)0x3a;     // Pins.GPIO_PIN_D5
        const Cpu.Pin d6 = (Cpu.Pin)0x3c;     // Pins.GPIO_PIN_D6
        const Cpu.Pin d7 = (Cpu.Pin)0x08;     // Pins.GPIO_PIN_D7

        static Cpu.Pin d10 = (Cpu.Pin)0x3d;                   // Pins.GPIO_PIN_D10
        static Cpu.AnalogChannel a0 = (Cpu.AnalogChannel)16;  // Pins.GPIO_PIN_A0
#endif
#if KS_MB9BF568
        const Cpu.Pin d8 = (Cpu.Pin)0x72;     // Pins.GPIO_PIN_D8
        const Cpu.Pin d9 = (Cpu.Pin)0x73;     // Pins.GPIO_PIN_D9
        const Cpu.Pin d4 = (Cpu.Pin)0x0b;     // Pins.GPIO_PIN_D4
        const Cpu.Pin d5 = (Cpu.Pin)0x0a;     // Pins.GPIO_PIN_D5
        const Cpu.Pin d6 = (Cpu.Pin)0x44;     // Pins.GPIO_PIN_D6
        const Cpu.Pin d7 = (Cpu.Pin)0x45;     // Pins.GPIO_PIN_D7

        static Cpu.Pin d10 = (Cpu.Pin)0x74;                   // Pins.GPIO_PIN_D10
        static Cpu.AnalogChannel a0 = (Cpu.AnalogChannel)15;  // Pins.GPIO_PIN_A0
#endif
#if GR_SAKURA
        const Cpu.Pin d8 = (Cpu.Pin)98;       // Pins.GPIO_PIN_D8 PC2 -> 98
        const Cpu.Pin d9 = (Cpu.Pin)99;       // Pins.GPIO_PIN_D9 PC3 -> 99
        const Cpu.Pin d4 = (Cpu.Pin)20;       // Pins.GPIO_PIN_D4 P24 -> 20
        const Cpu.Pin d5 = (Cpu.Pin)21;       // Pins.GPIO_PIN_D5 P25 -> 21
        const Cpu.Pin d6 = (Cpu.Pin)26;       // Pins.GPIO_PIN_D6 P32 -> 26 
        const Cpu.Pin d7 = (Cpu.Pin)27;       // Pins.GPIO_PIN_D7 P33 -> 27

        static Cpu.Pin d10 = (Cpu.Pin)100;                   // Pins.GPIO_PIN_D10
        static Cpu.AnalogChannel a0 = (Cpu.AnalogChannel)0;  // Pins.GPIO_PIN_A0
#endif

        public DfRobotLcdShield()
            : base(new GpioLcdTransferProvider(
                d8,
                d9,
                d4,
                d5,
                d6,
                d7))
        {

            backlight = new OutputPort(d10, true);
            analog = new AnalogInput(a0);

            this.Begin(16, 2);
            this.Clear();
        }

        public new bool Backlight
        {
            get { return backlight.Read(); }
            set { backlight.Write(value); }
        }

        public readonly static string[] ButtonNames = { "Right", "Up", "Down", "Left", "Select", "None" };

        public enum Buttons
        {
            Right,
            Up,
            Down,
            Left,
            Select,
            None
        }

        public Buttons ButtonState
        {
            get
            {
                double ar = (int)analog.Read();
                int adc_key = (int)ar;
                //Debug.Print("GPIO_A0 = " + adc_key.ToString());
                Debug.Print("GPIO_A0 = " + ar.ToString());
                if (adc_key > a_KEY_NONE) return Buttons.None;
                if (adc_key < a_KEY_RIGHT) return Buttons.Right;
                if (adc_key < a_KEY_UP) return Buttons.Up;
                if (adc_key < a_KEY_DOWN) return Buttons.Down;
                if (adc_key < a_KEY_LEFT) return Buttons.Left;
                if (adc_key < a_KEY_SELECT) return Buttons.Select;
                return Buttons.None;
            }
        }
    }
}
